package com.tencent.wxpay.protocol.request;

import com.tencent.wxpay.common.Configure;
import com.tencent.wxpay.common.RandomStringGenerator;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 基础请求数据对象
 */
public class BaseReqData implements Serializable {
    private static final long serialVersionUID = -3847368689470418501L;
    /**
     * 公众账号ID
     * 必填：是
     * 描述：微信分配的公众账号ID（企业号corpid即为此appId）
     */
    private String appid;
    /**
     * 商户号
     * 必填：是
     * 描述：微信支付分配的商户号
     */
    private String mch_id;
    /**
     * 随机字符串
     * 必填：是
     * 描述：随机字符串，不长于32位。推荐<a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3">随机数生成算法</a>
     */
    private String nonce_str;
    /**
     * 签名
     * 必填：是
     * 描述：签名，详见<a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3">签名生成算法</a>
     */
    private String sign;

    /**
     * 基础构造方法，设置 appid, mch_id, nonce_str
     */
    public BaseReqData() {
        this.appid = Configure.getAppid();
        this.mch_id = Configure.getMchid();
        this.nonce_str = RandomStringGenerator.getRandomStringByLength(32);
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getMch_id() {
        return mch_id;
    }

    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    /**
     * 将对象转换成map
     *
     * @param reqData BaseReqData的子类对象
     * @return
     */
    public Map<String, Object> toMap(Object reqData) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (reqData instanceof BaseReqData) {
            // 子类对象的属性
            Field[] fields = reqData.getClass().getDeclaredFields();
            putMap(fields, map, reqData);
            // 父类对象的属性
            Field[] pfields = reqData.getClass().getSuperclass().getDeclaredFields();
            putMap(pfields, map, reqData);
        }
        return map;
    }

    private Map<String, Object> putMap(Field[] fields, Map<String, Object> map, Object reqData) {
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object obj = field.get(reqData);
                if (obj != null) {
                    map.put(field.getName(), obj);
                }
                map.remove("serialVersionUID");
            } catch (Exception e) {
            }
        }
        return map;
    }
}
